package com.ljx.recruitment.security.aspect;

import com.ljx.recruitment.common.exception.ApiException;
import com.ljx.recruitment.security.annotation.ApiPermission;
import com.ljx.recruitment.security.common.UserContext;
import com.ljx.recruitment.security.util.UserUtil;
import com.ljx.recruitment.user.domain.dto.UserDto;
import com.ljx.recruitment.user.domain.entity.Permission;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: LiJunXi
 * @Description:
 * @Date: 2024-10-01  19:23
 */
@Component
@Aspect
public class PermissionAspect {

    @Around("@annotation(com.ljx.recruitment.security.annotation.ApiPermission)")
    public Object permissionAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取权限
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        ApiPermission annotation = methodSignature.getMethod().getAnnotation(ApiPermission.class);
        String[] permissions = annotation.permissions();
        // 检验用户是否拥有权限
        Boolean check = checkUser(permissions);
        if (!check){
            throw new ApiException("权限不足");
        }
        // 执行方法
        return joinPoint.proceed();
    }

    private Boolean checkUser(String[] permissions) {
        UserDto user = UserContext.getUser();
        if (UserUtil.checkIsPlatformAdmin()){
            return true;
        }
        if (Objects.isNull(user)){
            throw new ApiException("权限不足");
        }
        List<Permission> userPermissions = user.getPermissions();
        Map<String, Permission> permissionMap = userPermissions.stream().collect(Collectors.toMap(Permission::getName, Function.identity()));
        for (String permission : permissions) {
            if (!permissionMap.containsKey(permission)){
                return false;
            }
        }
        return true;
    }

}
